﻿// Copyright (c) Vitaly Kamiansky. All rights reserved. 
// See License.txt in the project root.

using Property.Reloaders;
using System;

namespace Property
{
    /// <summary>
    /// Contains words that extend the description 
    /// of a property's reload process.
    /// </summary>
    public static class ReloaderPrototypeExtensionsReactive
    {
        /// <summary>
        /// <para>... if the call passes through the specified filter (when) ...</para>
        /// <para>( ! ) Don't forget to dispose of what you create with this word.</para>
        /// </summary>
        /// <param name="filter">Tell me how to transform the sequence of reload calls.</param>
        /// <param name="testMode">Tell me if I have to ignore this word.</param>
        public static IReloaderPrototype<T> Filtered<T>(this IReloaderPrototype<T> source, Func<IObservable<object>, IObservable<object>> filter, bool testMode = false)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (filter == null) throw new ArgumentNullException("filter");

            return testMode ? source : new FilterReloaderDecoratorPrototype<T>(source, filter);
        }

        /// <summary>
        /// <para>... if the discriminator state passes through the specified sequence filter (when) ...</para>
        /// <para>( ! ) Don't forget to dispose of what you create with this word.</para>
        /// </summary>
        /// <param name="getState">Tell me how the state should be produced 
        /// based on its previous value.</param>
        /// <param name="filter">Tell me how to transform the sequence of reload calls 
        /// represented by the state values.</param>
        /// <param name="testMode">Tell me if I have to ignore this word.</param>
        public static IReloaderPrototype<T> Filtered<T, TState>(this IReloaderPrototype<T> source, Func<TState, TState> getState, Func<IObservable<TState>, IObservable<TState>> filter, bool testMode = false)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (getState == null) throw new ArgumentNullException("getState");
            if (filter == null) throw new ArgumentNullException("filter");

            return testMode ? source : new StateFilterReloaderDecoratorPrototype<T, TState>(source, getState, filter);
        }
    }
}